/*
 * IndiceDatos.cpp
 *
 *  Created on: May 20, 2012
 *      Author: lucasj
 */

#include "IndiceDatos.h"

DataIndex::IndiceDatos::IndiceDatos(Validador& validator):dimensionIndex(validator) {

}

void DataIndex::IndiceDatos::SetElem(std::string &linea, int cod) {
		this->map[cod] = linea;
		this->dimensionIndex.Cargar(linea, cod);
}

DataIndex::IndiceDatos::~IndiceDatos() {

}

void DataIndex::IndiceDatos::obtenerSiguientePosicion(unsigned int
					    &posAnterior, unsigned int &posActual, std::string &linea) {
	  	  posAnterior = posActual;
	  	  posActual = (linea.find("|", posAnterior + 1));
}

// Funcionamiento LLenarResultado:
// Recibe las dimensiones de la consulta a buscar en valor.
// lo parsea y lo busca en el índice de dimensiones. Cant Valores
// es la cantidad de valores de la consulta que se va contando
// a medida que se parsea la línea.

void DataIndex::IndiceDatos::LlenarResultado(std::string& valor,
		ResultIndex::IndiceResultado& resultIndex, int &cantValores) {
		unsigned int posActual = valor.find("|");
		unsigned int posAnterior = 0;
		std::string dimensionBuscar = valor.substr(posAnterior, posActual);
		this->dimensionIndex.Buscar(dimensionBuscar, resultIndex);
		++cantValores;
		obtenerSiguientePosicion(posAnterior, posActual, valor);
		while (posActual > posAnterior) {
			++cantValores;
			dimensionBuscar = valor.substr(posAnterior + 1, posActual - posAnterior - 1);
			this->dimensionIndex.Buscar(dimensionBuscar, resultIndex);
			obtenerSiguientePosicion(posAnterior, posActual, valor);
		}
}


void DataIndex::IndiceDatos::ImprimirResultados(std::list<int> &listaResultados, std::ostringstream &res) {
	iteratorListaResultado i;
	iteratorDatos j;
	for (i = listaResultados.begin(); i != listaResultados.end(); ++i) {
		j = this->map.begin();
		while (j != this->map.end() && (*i != j->first))
			++j;
		if (*i == j->first) {
			// res << j->first << " ";
			res << j->second << std::endl;
		}
	}


}

void DataIndex::IndiceDatos::Consultar(std::string &valor, std::ostringstream &res) {
	// std::ostringstream result;
	int cantValores = 0;
	ResultIndex::IndiceResultado resultIndex;
	LlenarResultado(valor, resultIndex, cantValores);
	// result << resultIndex;
	// std::cout << result.str();
	std::list<int> listaResultados;
	resultIndex.ObtenerDatos(cantValores, listaResultados);
	listaResultados.sort();
	ImprimirResultados(listaResultados, res);
}

std::ostringstream& DataIndex::operator<<(std::ostringstream& oss, DataIndex::IndiceDatos &indice) {
		iteratorDatos it;
		oss << "Indice Datos:" << std::endl;
		for (it = indice.map.begin(); it != indice.map.end(); ++it) {
			std::cout << it->first << " ";
			std::cout << it->second << std::endl;
		}
		std::cout << " " << std::endl;
		std::cout << "Indice Dimensiones:" << std::endl;
		oss << indice.dimensionIndex;
		return oss;
}


